package com.bondex.charter.service.edi;

import com.bondex.bondexapi.generator.service.GeneratorCodeService;
import com.bondex.charter.commons.BookingProcessTypeEnum;
import com.bondex.charter.commons.BusinessTypeEnum;
import com.bondex.charter.commons.CharterStatusEnum;
import com.bondex.charter.commons.Const;
import com.bondex.charter.commons.CutoffProcessTypeEnum;
import com.bondex.charter.commons.MailUtil;
import com.bondex.charter.dao.CharterBookingUnconfirmedMapper;
import com.bondex.charter.dao.CharterEdiRawMapper;
import com.bondex.charter.dao.CharterSiUnconfirmedMapper;
import com.bondex.charter.po.CharterBooking;
import com.bondex.charter.po.CharterBookingUnconfirmed;
import com.bondex.charter.po.CharterEdiRaw;
import com.bondex.charter.po.CharterSi;
import com.bondex.charter.po.CharterSiUnconfirmed;
import com.bondex.charter.po.CharterUserOperateLogVO;
import com.bondex.charter.pojo.ContainerInfo;
import com.bondex.charter.pojo.ediraw.EdiInputParam;
import com.bondex.charter.service.BaseService;
import com.bondex.charter.service.UserOperateLogService;
import com.bondex.global.pojo.TinyException;
import com.bondex.global.pojo.TransmissionModelV2;
import com.bondex.global.utils.JacksonUtil;
import com.bondex.viresult.dto.BondexMailDTO;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 接受EDI变更请求相关
 * Created by JD on 2021/9/16.
 */
@Service
public class EdiRawService extends BaseService {

	@Resource
	private CharterEdiRawMapper charterEdiRawMapper;
	@Resource
	private CharterBookingUnconfirmedMapper charterBookingUnconfirmedMapper;
	@Resource
	private CharterSiUnconfirmedMapper charterSiUnconfirmedMapper;

	@Autowired
	private GeneratorCodeService generatorCodeService;
	@Autowired
	private MailUtil mailUtil;
	@Autowired
	private UserOperateLogService userOperateLogService;
	@Autowired
	private DataSourceTransactionManager transactionManager;

	@Value("${charter.application_id}")
	private String APPLICATION_ID;

	/**
	 * 接受EDI处理的总体方法
	 * <p>
	 * 1. 本航次以下字段默认如下
	 * 签单地：QINGDAO,CHINA
	 * 运输条款：HOOK-HOOK
	 * 付款方式：FREIGHT PREPAID
	 * 付款地：NINGBO
	 * 2. 报文解析时，FTX部分不需要做处理，按照原内容直接放到详情页面的提单备注处
	 *
	 * @param sMsg
	 */
	public void handlerEdiRaw(String sMsg) {
		boolean bIsSI = false;
		CharterEdiRaw oInfo = null;
		try {
			//报文解析&有效性判断
			if (StringUtils.isBlank(sMsg)) {
				throw new TinyException("入参为空。");
			}
			TransmissionModelV2<EdiInputParam> oParam = JacksonUtil.readValue(sMsg, new TypeReference<TransmissionModelV2<EdiInputParam>>() {
			});
			if (oParam == null) {
				throw new TinyException("入参转换失败。");
			}
			Integer nID = oParam.getMain().getId();
			if (nID == null || nID <= 0) {
				throw new TinyException("入参的ID为空。");
			}

			//到charter_edi_raw表中查询对应数据
			oInfo = charterEdiRawMapper.selectByPrimaryKey(nID);
			if (oInfo == null) {
				throw new TinyException("未能在数据库中找到ID为[" + nID + "]的数据。");
			} else if (StringUtils.isBlank(oInfo.getEdiMsgType())) {
				throw new TinyException("未知的报文类型。");
			}


			//数据标准处理
			switch (oInfo.getEdiMsgType()) {
				case Const.EDI_MSG_TYPE_BOOKING: {
					replaceIntoBooking(oInfo);
					break;
				}
				case Const.EDI_MSG_TYPE_SI: {
					bIsSI = true;
					replaceIntoSI(oInfo);
					break;
				}
			}

			if (bIsSI) {
				insertUserOperateLog4Si(oInfo, sMsg, "数据插入成功。");
			} else {
				insertUserOperateLog4Booking(oInfo, sMsg, "数据插入成功。");
			}
		} catch (Exception e) {
			e.printStackTrace();
			if (bIsSI) {
				insertUserOperateLog4Si(oInfo, sMsg, e.getMessage());
			} else {
				insertUserOperateLog4Booking(oInfo, sMsg, e.getMessage());
			}
		}
	}

	//region 订舱表替换

	/**
	 * 订舱报文覆盖规则
	 * 1.BOOKING第一次发送，状态变更为订舱待审核
	 * 2.订舱待审核状态，BOOKING可重复覆盖
	 * 3.已放舱状态，再次发送BOOKING时，对 品名，件重尺，箱型箱量 进行对比
	 *      没有更改，则自动覆盖
	 *      任意一项有更改，则状态变更为订舱更改，需要操作再次审批，不一致字段展示内容对比
	 * 4.已拒绝及已退舱状态，不接受覆盖
	 * 暂定，拆票合票后，不允许通过报文调整信息
	 */

	/**
	 * 替换到订舱表中
	 *
	 * @return
	 * @throws Exception
	 */
	private void replaceIntoBooking(CharterEdiRaw oInfo) throws Exception {
		int nEffect = 0;
		TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
		try {

			//通过入参中的客户号，查询是否存在对应的订舱单
			CharterBooking oBooking = getBookingByEdi(oInfo);
			if (oBooking == null || oBooking.getId() == null || oBooking.getId() <= 0) {
				//不存在对应数据

				//获取流水号 BK210912001
				String sOrderNo = generatorCodeService.generatorCode(APPLICATION_ID, Const.GENERATOR_PROFILE_BK, "IT032");

				//插入到订舱表中
				CharterBooking oInsert = transformEdi2Booking(oInfo);
				oInsert.setOrderNo(sOrderNo);
				oInsert.setDelFlg((byte) 0);
				oInsert.setBookingStatus(CharterStatusEnum.BOOKING_NEW.getValueDBString());
				oInsert.setCreateDate(new Date());

				nEffect = 0;
				nEffect = charterBookingMapper.insertSelective(oInsert);
				if (nEffect <= 0) {
					throw new TinyException("插入数据库失败。");
				}

			} else {

				//通过查询出来的委托号，判断是否存在 已放舱且已更改的

				if (isRollOver(oBooking)) {
					throw new TinyException("订舱委托已经甩货，禁止操作数据。");
				}

				CharterStatusEnum oBookingStatus = getBookingStatus(oBooking);

				switch (oBookingStatus) {
					case BOOKING_NEW: //订舱待审核
					case BOOKING_PENDING: //待定
					{
						//状态未订舱待审核、待定，更新主表数据
						CharterBooking oUpdate = transformEdi2Booking(oInfo);
						oUpdate.setId(oBooking.getId());
						oUpdate.setOrderNo(oBooking.getOrderNo());
						oUpdate.setDelFlg((byte) 0);
						oUpdate.setBookingStatus(oBooking.getBookingStatus());
						oUpdate.setModifyDate(new Date());

						nEffect = 0;
						nEffect = charterBookingMapper.updateByPrimaryKeySelective(oUpdate);
						if (nEffect <= 0) {
							throw new TinyException("更新数据库失败。");
						}
						break;
					}
					case BOOKING_RELEASE://已放舱
					{
						//插入冗余表并调整状态

						if (isSameKeyInformation(oInfo, oBooking)) {
							//关键信息一致，直接覆盖报文
							CharterBooking oUpdate = transformEdi2Booking(oInfo);
							oUpdate.setId(oBooking.getId());
							oUpdate.setOrderNo(oBooking.getOrderNo());
							oUpdate.setDelFlg((byte) 0);
							oUpdate.setBookingStatus(oBooking.getBookingStatus());
							oUpdate.setModifyDate(new Date());

							nEffect = 0;
							nEffect = charterBookingMapper.updateByPrimaryKeySelective(oUpdate);
							if (nEffect <= 0) {
								throw new TinyException("更新数据库失败。");
							}
						} else {
							//关键信息不一致，状态变更

							CharterBooking oUpdate = new CharterBooking();
							oUpdate.setId(oBooking.getId());
							oUpdate.setOrderNo(oBooking.getOrderNo());
							oUpdate.setDelFlg((byte) 0);
							oUpdate.setBookingStatus(CharterStatusEnum.BOOKING_AMENDMENT.getValueDBString());
							oUpdate.setModifyDate(new Date());

							nEffect = 0;
							nEffect = charterBookingMapper.updateByPrimaryKeySelective(oUpdate);
							if (nEffect <= 0) {
								throw new TinyException("更新数据库失败。");
							}

							//追加到冗余表中
							CharterBooking oTemp = transformEdi2Booking(oInfo);
							String sTemp = JacksonUtil.writeValue(oTemp);
							CharterBookingUnconfirmed oUnconfirmed = JacksonUtil.readValue(sTemp, CharterBookingUnconfirmed.class);
							oUnconfirmed.setId(null);
							oUnconfirmed.setCreateDate(new Date());

							nEffect = 0;
							nEffect = charterBookingUnconfirmedMapper.updateByPrimaryKeySelective(oUnconfirmed);
							if (nEffect <= 0) {
								throw new TinyException("更新数据库冗余表失败。");
							}

						}

						break;
					}
					case BOOKING_AMENDMENT: //订舱更改
					case BOOKING_REJECTED: //拒绝订舱
					case BOOKING_CANCEL: //退舱
					{
						//不允许再次更改了
						throw new TinyException("当前订舱单状态为" + oBookingStatus.getName() + "，将不进行操作。");
					}
				}
			}

			transactionManager.commit(transactionStatus);
		} catch (Exception e) {
			transactionManager.rollback(transactionStatus);
			throw e;
		}
	}

	/**
	 * 根据EDI报文获取订舱单信息
	 */
	private CharterBooking getBookingByEdi(CharterEdiRaw oInfo) throws Exception {
		if (StringUtils.isBlank(oInfo.getCustomerNo())) {
			throw new TinyException("客户订单号为空时，将不进行报文处理。");
		}

		List<CharterBooking> list = charterBookingMapper.selectByCustomerNo(oInfo.getCustomerNo());
		if (list == null || list.size() <= 0) {
			throw new TinyException("未能通过客户订单号获取到有效的数据。");
		} else if (list.size() > 1) {
			throw new TinyException("通过客户订单号获取到了多条数据。");
		}
		return list.get(0);
	}

	/**
	 * 根据数据库中的值，获取订舱状态
	 */
	private CharterStatusEnum getBookingStatus(CharterBooking oBooking) throws Exception {
		CharterStatusEnum e = null;
		String s = oBooking.getBookingStatus();
		switch (s) {
			case "0": {
				e = CharterStatusEnum.BOOKING_NEW;
				break;
			}
			case "2": {
				e = CharterStatusEnum.BOOKING_PENDING;
				break;
			}
			case "1": {
				e = CharterStatusEnum.BOOKING_RELEASE;
				break;
			}
			case "3": {
				e = CharterStatusEnum.BOOKING_AMENDMENT;
				break;
			}
			case "10": {
				e = CharterStatusEnum.BOOKING_REJECTED;
				break;
			}
			case "11": {
				e = CharterStatusEnum.BOOKING_CANCEL;
				break;
			}
			default: {
				throw new TinyException("未知的订舱状态。");
			}
		}
		return e;
	}

	/**
	 * 判断EDI报文与订舱单的关键信息是否一致
	 */
	private boolean isSameKeyInformation(CharterEdiRaw oInfo, CharterBooking oBooking) throws Exception {
		String sContainerNoAndType = "";
		if (oInfo.getContainerInfo() != null) {
			List<ContainerInfo> oContainers = JacksonUtil.readValue((String) oInfo.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
			});
			sContainerNoAndType = convertContainerNoAndType(oContainers);
		}

		return oInfo.getDescription().equals(oBooking.getDescription())
				&& oInfo.getNoOfPackage() == oBooking.getNoOfPackage()
				&& (oInfo.getGrossWeight() != null && oInfo.getGrossWeight().compareTo(oBooking.getGrossWeight()) == 0)
				&& (oInfo.getVolume() != null && oInfo.getVolume().compareTo(oBooking.getVolume()) == 0)
				&& sContainerNoAndType.equals(oBooking.getContainerNoAndType())
				;
	}

	/**
	 * 将EDI报文转换为订舱报文
	 */
	private CharterBooking transformEdi2Booking(CharterEdiRaw oEdi) throws Exception {
		String sInfo = JacksonUtil.writeValue(oEdi);
		CharterBooking oBooking = JacksonUtil.readValue(sInfo, CharterBooking.class);
		oBooking.setId(null);

		if (oBooking.getNoOfPackage() == null) oBooking.setNoOfPackage(0L);
		if (oBooking.getGrossWeight() == null) oBooking.setGrossWeight(new BigDecimal(0));
		if (oBooking.getVolume() == null) oBooking.setVolume(new BigDecimal(0));

		if (oBooking.getExtendInfoBean() != null) {
			oBooking.setExtendInfo(JacksonUtil.writeValue(oBooking.getExtendInfoBean()));
		}

		if (oBooking.getContainerInfos() != null && oBooking.getContainerInfos().size() > 0) {
			oBooking.setContainerInfo(JacksonUtil.writeValue(oBooking.getContainerInfos()));
		}

		if (oBooking.getContainerInfo() != null) {
			List<ContainerInfo> oContainers = JacksonUtil.readValue((String) oBooking.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
			});
			String sContainer = convertContainerNoAndType(oContainers);
			oBooking.setContainerNoAndType(sContainer);
		}
		oBooking.setBulkyHeavyFlag(getBulkyHeavyFlagOfBooking(oBooking));

		return oBooking;
	}

	/**
	 * 判断订舱委托是否甩货
	 */
	private boolean isRollOver(CharterBooking oBooking) throws Exception {
		return oBooking != null
				&& oBooking.getIsRollOver() != null
				&& CharterStatusEnum.BOOKING_ROLL_OVER.getValueDB() == (int) oBooking.getIsRollOver()
				;
	}

	//endregion

	//region 截单表替换

	/**
	 * 截单报文覆盖规则
	 * 1.SI第一次发送，状态变更为截单待确认，截单内容与放舱内容进行对比，不一致字段展示内容对比
	 * 2.截单待确认状态，再次发送SI直接覆盖
	 * 3.已截单状态，接收SI，状态变更为截单更改，最新截单内容与上一版已保存截单内容进行对比，不一致字段展示内容对比
	 *      操作进行内容审批，审批通过则生成格式单并发送客户，页面保存最新截单内容；审批不通过点击拒绝，页面内容恢复上一版保存截单内容，并发送邮件通知客户拒绝原因，状态变更至已截单
	 * 4.超过系统截单时间后，处理方式同已截单状态，改单内容审批通过时，同时系统自动标记改单状态
	 * 5.AMS已申报的情况下，处理方式同已截单状态，同时，操作打开最新截单页面时，弹窗提示：此票AMS已申报，如有改单请注意AMS更改
	 *
	 * 接收到截单SI时，箱型箱量与放舱箱型箱量进行对比，不一致则不接受该SI，并发送邮件给客户，通知截单箱型箱量与订舱不一致，请核对后重新发送
	 */

	/**
	 * 替换到截单表中
	 *
	 * @return
	 * @throws Exception
	 */
	private void replaceIntoSI(CharterEdiRaw oInfo) throws Exception {
		int nEffect = 0;
		TransactionStatus transactionStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());
		try {

			//根据入参的客户号，获取订舱委托
			CharterBooking oBooking = getBookingByEdi(oInfo);

			//根据入参的客户号，获取截单委托
			CharterSi oSi = getSiByEdi(oInfo);
			CharterSi oSiNew = transformEdi2Si(oInfo);
			CharterStatusEnum oBookingStatus = getBookingStatus(oBooking);

			if (oBooking == null) {
				throw new TinyException("未录入订舱委托，将不处理截单委托。");
			} else if (isRollOver(oBooking)) {
				throw new TinyException("订舱委托已经甩货，将不处理截单委托。");
			} else if (CharterStatusEnum.BOOKING_REJECTED == oBookingStatus) {
				throw new TinyException("订舱委托已经" + oBookingStatus.getName() + "，将不处理截单委托。");
			} else if (CharterStatusEnum.BOOKING_CANCEL == oBookingStatus) {
				throw new TinyException("订舱委托已经" + oBookingStatus.getName() + "，将不处理截单委托。");
			} else if (isSameKeyInformation(oBooking, oSiNew)) {
				throw new TinyException("需要变更的截单委托与既存的订舱委托的关键信息不一致，将不处理截单委托。");
			}

			if (oSi == null) {
				switch (oBookingStatus) {
					case BOOKING_RELEASE: {

						//插入到截单表中
						oSiNew.setOrderNo(oBooking.getOrderNo());
						oSiNew.setDelFlg((byte) 0);
						oSiNew.setSiStatus(CharterStatusEnum.SI_NEW.getValueDBString());
						oSiNew.setCreateDate(new Date());

						nEffect = 0;
						nEffect = charterSiMapper.insertSelective(oSiNew);
						if (nEffect <= 0) {
							throw new TinyException("插入数据库失败。");
						}

					}
					default: {
						throw new TinyException("订舱委托状态为" + oBookingStatus.getName() + "，将不插入截单委托。");
					}
				}
			} else {

				CharterStatusEnum oSiStatus = getSiStatus(oSi);

				switch (oSiStatus) {
					case SI_NEW: {
						//如果截单委托存在且状态为待确认，直接更新
						oSiNew.setId(oSi.getId());
						oSiNew.setOrderNo(oSi.getOrderNo());
						oSiNew.setDelFlg((byte) 0);
						oSiNew.setSiStatus(oSi.getSiStatus());
						oSiNew.setModifyDate(new Date());

						nEffect = 0;
						nEffect = charterSiMapper.updateByPrimaryKeySelective(oSiNew);
						if (nEffect <= 0) {
							throw new TinyException("更新数据库失败。");
						}
						break;
					}
					case SI_CONFIRMED: //已截单
					case SI_AMS_FILING: //AMS已申报
					{
						//如果截单委托存在且状态为已截单，追加到冗余表

						CharterSi oUpdate = new CharterSi();
						oUpdate.setId(oSi.getId());
						oUpdate.setOrderNo(oSi.getOrderNo());
						oUpdate.setDelFlg((byte) 0);
						oUpdate.setSiStatus(CharterStatusEnum.SI_BL_AMENDMENT.getValueDBString());
						oUpdate.setModifyDate(new Date());

						nEffect = 0;
						nEffect = charterSiMapper.updateByPrimaryKeySelective(oUpdate);
						if (nEffect <= 0) {
							throw new TinyException("更新数据库失败。");
						}

						//追加到冗余表中
						String sTemp = JacksonUtil.writeValue(oSiNew);
						CharterSiUnconfirmed oUnconfirmed = JacksonUtil.readValue(sTemp, CharterSiUnconfirmed.class);
						oUnconfirmed.setId(null);
						oUnconfirmed.setCreateDate(new Date());

						nEffect = 0;
						nEffect = charterSiUnconfirmedMapper.updateByPrimaryKeySelective(oUnconfirmed);
						if (nEffect <= 0) {
							throw new TinyException("更新数据库冗余表失败。");
						}

						break;
					}
					case SI_BL_AMENDMENT:
					case SI_BL_RELEASE: {
						//不允许再次更改了
						throw new TinyException("当前截单状态为" + oSiStatus.getName() + "，将不进行操作。");
					}
				}

			}

			transactionManager.commit(transactionStatus);
		} catch (Exception e) {
			transactionManager.rollback(transactionStatus);
			throw e;
		}
	}

	/**
	 * 根据EDI报文获取截单信息
	 */
	private CharterSi getSiByEdi(CharterEdiRaw oInfo) throws Exception {
		if (StringUtils.isBlank(oInfo.getCustomerNo())) {
			throw new TinyException("客户订单号为空时，将不进行报文处理。");
		}

		List<CharterSi> list = charterSiMapper.selectByCustomerNo(oInfo.getCustomerNo());
		if (list == null || list.size() <= 0) {
			throw new TinyException("未能通过客户订单号获取到有效的数据。");
		} else if (list.size() > 1) {
			throw new TinyException("通过客户订单号获取到了多条数据。");
		}
		return list.get(0);
	}

	/**
	 * 通过EDI报文生成截单委托对象
	 */
	private CharterSi transformEdi2Si(CharterEdiRaw oEdi) throws Exception {
		String sInfo = JacksonUtil.writeValue(oEdi);
		CharterSi oSi = JacksonUtil.readValue(sInfo, CharterSi.class);
		oSi.setId(null);

		if (oSi.getNoOfPackage() == null) oSi.setNoOfPackage(0L);
		if (oSi.getGrossWeight() == null) oSi.setGrossWeight(new BigDecimal(0));
		if (oSi.getVolume() == null) oSi.setVolume(new BigDecimal(0));

		if (oSi.getContainerInfo() != null) {
			List<ContainerInfo> oContainers = JacksonUtil.readValue((String) oSi.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
			});
			String sContainer = convertContainerNoAndType(oContainers);
			oSi.setContainerNoAndType(sContainer);
		}
		oSi.setBulkyHeavyFlag(getBulkyHeavyFlagOfSi(oSi));

		return oSi;
	}

	/**
	 * 订舱与截单的数据一致性判断
	 * 接收到截单SI时，箱型箱量与放舱箱型箱量进行对比，不一致则不接受该SI，并发送邮件给客户，通知截单箱型箱量与订舱不一致，请核对后重新发送
	 */
	private boolean isSameKeyInformation(CharterBooking oBooking, CharterSi oSi) throws Exception {

		List<ContainerInfo> oContainers = JacksonUtil.readValue((String) oBooking.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
		});
		String sContainerNoAndTypeOfBooking = convertContainerNoAndType(oContainers);

		if (sContainerNoAndTypeOfBooking.equals(oSi.getContainerNoAndType())) {
			//箱型箱量一致
			return true;
		}

		//region 订舱委托与截单委托的箱型箱量不一致，需要发送邮件给客户
		BondexMailDTO bondexMailDTO = new BondexMailDTO();
		//模板id
		bondexMailDTO.setId("44fb9392-aa61-4168-8518-305f0f0559e3");
		//收件人
		bondexMailDTO.setReceiveTo("kayn@bondex.com.cn");
		//抄送人
		bondexMailDTO.setCc("jiaodian@bondex.com.cn");
		//主题
		bondexMailDTO.setSubject("SI Rejected " + oSi.getBlNo() + " " + oSi.getCustomerNo() + " " + oSi.getContainerNoAndType());
		//正文
		Map<String, Object> map = new HashMap<>();
		map.put("orderNo", oSi.getCustomerNo());
		map.put("bookingNo", oSi.getBlNo());
		map.put("bookingContainerNoAndType", oBooking.getContainerNoAndType());
		map.put("siContainerNoAndType", oSi.getContainerNoAndType());
		map.put("refusereason", "截单箱型箱量与放舱不一致，请确认后重新提交SI");
		bondexMailDTO.setVariableContext(map);
		// 推送邮件
		mailUtil.pushMail(bondexMailDTO);
		//endregion

		return false;
	}

	/**
	 * 获取截单状态
	 */
	private CharterStatusEnum getSiStatus(CharterSi oSi) throws Exception {
		CharterStatusEnum e = null;
		String s = oSi.getSiStatus();
		switch (s) {
			case "0": {
				e = CharterStatusEnum.SI_NEW;
				break;
			}
			case "1": {
				e = CharterStatusEnum.SI_CONFIRMED;
				break;
			}
			case "3": {
				e = CharterStatusEnum.SI_BL_AMENDMENT;
				break;
			}
			case "4": {
				e = CharterStatusEnum.SI_AMS_FILING;
				break;
			}
			case "5": {
				e = CharterStatusEnum.SI_BL_RELEASE;
				break;
			}
			default: {
				throw new TinyException("未知的截单状态。");
			}
		}
		return e;
	}


	//endregion

	//region 发送日志内部使用

	/**
	 * 组装日志实体
	 */
	private void insertUserOperateLog4Booking(CharterEdiRaw oInfo, String sRequestInfo, String sResponseInfo) {
		if (oInfo == null) oInfo = new CharterEdiRaw();
		CharterUserOperateLogVO oInsert = new CharterUserOperateLogVO();
		oInsert.setBusinessType(BusinessTypeEnum.BOOKING.getName());
		oInsert.setProcessType(BookingProcessTypeEnum.BOOKING_EDI.getName());
		insertUserOperateLog(oInsert, oInfo.getOrderNo(), "", oInfo.getBlNo(), oInfo.getCustomerNo(), sRequestInfo, sResponseInfo);
	}


	/**
	 * 组装日志实体
	 */
	private void insertUserOperateLog4Si(CharterEdiRaw oInfo, String sRequestInfo, String sResponseInfo) {
		if (oInfo == null) oInfo = new CharterEdiRaw();
		CharterUserOperateLogVO oInsert = new CharterUserOperateLogVO();
		oInsert.setBusinessType(BusinessTypeEnum.CUTOFF.getName());
		oInsert.setProcessType(CutoffProcessTypeEnum.CUTOFF_EDI.getName());
		insertUserOperateLog(oInsert, oInfo.getOrderNo(), "", oInfo.getBlNo(), oInfo.getCustomerNo(), sRequestInfo, sResponseInfo);
	}

	/**
	 * 组装日志实体
	 */
	private void insertUserOperateLog(CharterUserOperateLogVO oInsert
			, String sOrderNo, String sBookingNo, String sBlNo, String sCustomerNo
			, String sRequestInfo, String sResponseInfo) {
		oInsert.setOrderNo(sOrderNo);
		oInsert.setBookingNo(sBookingNo);
		oInsert.setBlNo(sBlNo);
		oInsert.setCustomerNo(sCustomerNo);
		oInsert.setRequestInfo(sRequestInfo);
		oInsert.setResponseInfo(sResponseInfo);
		oInsert.setCreateBy("admin");
		oInsert.setCreateDate(new Date());
		userOperateLogService.insertCharterUserOperateLog(oInsert);
	}

	//endregion
}
